package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"strings"
	"sync"
	"time"

	"github.com/PuerkitoBio/goquery"
)

const BASE_URL = "https://so.gushiwen.cn/shiwens/default.aspx"

// 一百首, 修改数组数量即可控制下载数量
var contentArray [101]string

var finishCount = 0

var mu sync.Mutex

var finishChann chan int = make(chan int)

func main() {
	startTime := time.Now()
	for i := 0; i < 50; i++ {
		tempI := i
		go func() {
			response, err := http.Get(fmt.Sprintf("%s?page=%d", BASE_URL, tempI))
			if err != nil {
				log.Panicln("请求失败", err)
			}

			bodyBytes, err := io.ReadAll(response.Body)
			if err != nil {
				log.Panicln("解析响应异常", err)
			}

			bodyStr := string(bodyBytes)
			// log.Println("bodyStr:", bodyStr)
			document, err := goquery.NewDocumentFromReader(strings.NewReader(bodyStr))
			if err != nil {
				log.Panicln("Goquery 解析异常", err)
			}

			var count = 0
			document.Find(`div[id^=zhengwen]`).Each(func(i int, s *goquery.Selection) {
				count++
			})

			document.Find(`div[id^=zhengwen]`).Each(func(i2 int, s *goquery.Selection) {
				go handleContent(tempI*count+i2, s)
			})
		}()

	}

	<-finishChann

	log.Printf("%d首已完成\n", len(contentArray)-1)

	var allContent = ""
	for _, content := range contentArray[:] {
		allContent += content + "\n\n"
	}
	os.WriteFile("./100首.txt", []byte(allContent), 0644)

	log.Println("经过时间", time.Since(startTime))
}

// 处理正文
func handleContent(index int, selection *goquery.Selection) {
	if index > len(contentArray)-1 {
		return
	}

	mu.Lock()
	if finishCount > len(contentArray) {
		mu.Unlock()
		return
	}
	mu.Unlock()

	// 替换<br/>为换行符
	selection.Find("br").ReplaceWithHtml("\n")

	selection.Children().Each(func(i int, selection2 *goquery.Selection) {
		// log.Println(strings.TrimSpace(selection2.Text()))
		// i-1: 标题, i-2: 作者〔年代〕, i-3: 正文

		contentArray[index] += strings.TrimSpace(selection2.Text()) + "\n"
	})

	log.Println("已完成", index)
	mu.Lock()
	finishCount++
	mu.Unlock()

	mu.Lock()
	if finishCount > len(contentArray)-1 {
		// log.Println("完成")
		finishChann <- 1
	}
	mu.Unlock()
}
